package com.ruoyi.system.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.domain.TreeSelect;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanValidators;
import com.ruoyi.system.domain.SysStaff;
import com.ruoyi.system.domain.SysStaffDeptEnterpriseRel;
import com.ruoyi.system.domain.request.SysStaffRequest;
import com.ruoyi.system.mapper.SysStaffDeptEnterpriseRelMapper;
import com.ruoyi.system.mapper.SysStaffMapper;
import com.ruoyi.system.service.ISysDeptEnterpriseService;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.service.ISysStaffDeptEnterpriseRelService;
import com.ruoyi.system.service.ISysStaffService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.validation.Validator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 教职员工Service业务层处理
 *
 * @author ruoyi
 * @date 2024-11-14
 */
@Service
public class SysStaffServiceImpl extends ServiceImpl<SysStaffMapper, SysStaff> implements ISysStaffService {
    private static final Logger log = LoggerFactory.getLogger(SysStaffServiceImpl.class);
    @Autowired
    protected Validator validator;
    //@Autowired
    //private SysUserMapper userMapper;
    @Resource
    private SysStaffMapper sysStaffMapper;
    @Resource
    private SysStaffDeptEnterpriseRelMapper sysStaffDeptEnterpriseRelMapper;
    @Autowired
    private ISysDeptService deptService;

    @Autowired
    private ISysDeptEnterpriseService sysDeptEnterpriseService;
    @Autowired
    private ISysStaffDeptEnterpriseRelService sysStaffDeptEnterpriseRelService;

    /**
     * 查询教职员工
     *
     * @param staffId 教职员工主键
     * @return 教职员工
     */
    @Override
    public SysStaff selectSysStaffByStaffId(Long staffId) {
        return sysStaffMapper.selectSysStaffByStaffId(staffId);
    }

    /**
     * 查询教职员工列表
     *
     * @param sysStaffRequest 教职员工
     * @return 教职员工
     */
    @Override
    public List<SysStaff> selectSysStaffList(SysStaffRequest sysStaffRequest) {
        return sysStaffMapper.selectSysStaffList(sysStaffRequest);
    }

    /**
     * 新增教职员工
     *
     * @param sysStaff 教职员工
     * @return 结果
     */
    @Override
    public int insertSysStaff(SysStaff sysStaff) {
        sysStaff.setCreateTime(DateUtils.getNowDate());
        return sysStaffMapper.insertSysStaff(sysStaff);
    }

    /**
     * 修改教职员工
     *
     * @param sysStaff 教职员工
     * @return 结果
     */
    @Override
    public int updateSysStaff(SysStaff sysStaff) {
        sysStaff.setUpdateTime(DateUtils.getNowDate());
        return sysStaffMapper.updateSysStaff(sysStaff);
    }

    /**
     * 批量删除教职员工
     *
     * @param staffIds 需要删除的教职员工主键
     * @return 结果
     */
    @Override
    @Transactional
    public int deleteSysStaffByStaffIds(Long[] staffIds) {
        sysStaffDeptEnterpriseRelMapper.deleteByStaffIds(staffIds);
        return sysStaffMapper.deleteSysStaffByStaffIds(staffIds);
    }

    /**
     * 删除教职员工信息
     *
     * @param staffId 教职员工主键
     * @return 结果
     */
    @Override
    public int deleteSysStaffByStaffId(Long staffId) {
        return sysStaffMapper.deleteSysStaffByStaffId(staffId);
    }

    @Override
    public String importData(List<SysStaff> sysStaffList, boolean updateSupport, String operName) {
        if (StringUtils.isNull(sysStaffList) || sysStaffList.size() == 0) {
            throw new ServiceException("导入数据不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        for (SysStaff sysStaff : sysStaffList) {
            try {
                //重名问题 不做更新，只新增
                //SysStaff staffDB = sysStaffMapper.selectByName(sysStaff.getName());
                //if (StringUtils.isNull(staffDB)) {
                BeanValidators.validateWithException(validator, sysStaff);
                //deptService.checkDeptDataScope(sysStaff.getDeptId());
                sysStaff.setCreateBy(operName);
                sysStaffMapper.insertSysStaff(sysStaff);
                successNum++;
                successMsg.append("<br/>" + successNum + "、姓名 " + sysStaff.getName() + " 导入成功");
                //} else if (updateSupport) {
                //    BeanValidators.validateWithException(validator, sysStaff);
                //    checkUserAllowed(staffDB);
                //    checkUserDataScope(staffDB.getUserId());
                //    deptService.checkDeptDataScope(sysStaff.getDeptId());
                //    sysStaff.setStaffId(staffDB.getStaffId());
                //    sysStaff.setUpdateBy(operName);
                //    sysStaffMapper.updateSysStaff(sysStaff);
                //    successNum++;
                //    successMsg.append("<br/>" + successNum + "、姓名 " +  sysStaff.getName() + " 更新成功");
                //} else {
                //    failureNum++;
                //    failureMsg.append("<br/>" + failureNum + "、姓名 " +  sysStaff.getName() + " 已存在");
                //}
            } catch (Exception e) {
                failureNum++;
                String msg = "<br/>" + failureNum + "、姓名 " + sysStaff.getName() + " 导入失败：";
                failureMsg.append(msg).append(e.getMessage());
                log.error(msg, e);
            }
        }
        if (failureNum > 0) {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new ServiceException(failureMsg.toString());
        } else {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }

    @Override
    public List<TreeSelect> buildStaffTreeSelect() {

        List<TreeSelect> treeSelects = this.deptService.selectDeptTreeList(new SysDept());

        populateStaffForTreeSelect(treeSelects);

        return treeSelects;
    }

    @Override
    public List<HashMap<String, Integer>> queryDeptStaffCount() {

        return this.sysStaffMapper.queryDeptStaffCount();
    }

    @Override
    public List<TreeSelect> buildEnterpriseStaffTreeSelect() {


        List<TreeSelect> treeSelects = this.sysDeptEnterpriseService.selectDeptTreeList(new SysDept());


        populateStaffForTreeSelect(treeSelects);

        return treeSelects;

    }

    private void populateStaffForTreeSelect(List<TreeSelect> treeSelects) {
        Optional.ofNullable(treeSelects).orElseGet(CollUtil::newArrayList).forEach(treeSelect -> {
            HashSet<Long> staffIdSet = new HashSet<>(sysStaffDeptEnterpriseRelService.listObjs(
                    Wrappers.<SysStaffDeptEnterpriseRel>lambdaQuery()
                            .eq(SysStaffDeptEnterpriseRel::getEnterpriseDeptId, treeSelect.getId())
                            .select(SysStaffDeptEnterpriseRel::getStaffId), Convert::toLong));

            if (CollUtil.isNotEmpty(staffIdSet)) {
                List<SysStaff> staffList = this.sysStaffMapper.selectList(new LambdaQueryWrapper<SysStaff>()
                        .in(SysStaff::getStaffId, staffIdSet));

                List<TreeSelect> staffTreeSelects = staffList.stream()
                        .map(staff -> {
                            TreeSelect staffNode = new TreeSelect();
                            staffNode.setId(staff.getStaffId());
                            staffNode.setType("staff");
                            staffNode.setLabel(staff.getName());
                            return staffNode;
                        })
                        .collect(Collectors.toList());
                if (CollUtil.isNotEmpty(staffTreeSelects)) {
                    List<TreeSelect> children = treeSelect.getChildren();
                    if (CollUtil.isNotEmpty(children)) {
                        children.addAll(staffTreeSelects);
                    } else {
                        treeSelect.setChildren(staffTreeSelects);
                    }
                }
            }

            if (CollUtil.isNotEmpty(treeSelect.getChildren())) {
                populateStaffForTreeSelect(treeSelect.getChildren());
            }
        });
    }
}
